#pragma once

class CReaderStream
{
public:
	char* _buffer;
	SIZE_ST _rpos;
	SIZE_ST _wpos;
	SIZE_ST _capacity;
public:
	inline int rpos(){ return _rpos; }
	inline int wpos(){ return _wpos; }
	inline int capacity(){ return _capacity; }
	inline int length(){ return _wpos; }
	inline char* c_str(){ return _buffer; }
	void reset()
	{
		if (_buffer != NULL && _capacity > 0)
		{
			memset(_buffer, 0, _capacity);
		}
		_rpos = 0;
		_wpos = 0;

	}
	void setCapacity(SIZE_ST length)
	{
		if (length < 0 || length == _capacity)
			return;
		if (length == 0)
		{
			if (_buffer)
			{
				free(_buffer);
				_buffer = NULL;
			}
			return;
		}
		char* temp = (char*)malloc(_capacity);
		memset(temp, 0, _capacity);
		memcpy(temp, _buffer, _capacity);
		if (_buffer)
		{
			free(_buffer);
			_buffer = NULL;
		}
		_buffer = (char*)malloc(length);
		memset(_buffer, 0, length);
		memcpy(_buffer, temp, length > _capacity ? _capacity : length);
		_capacity = length;
		free(temp);
		temp = NULL;
	}
	void clear()
	{
		if (_buffer)
		{
			free(_buffer);
			_buffer = NULL;
		}
		_rpos = 0;
		_wpos = 0;
		_capacity = 0;
	}

	virtual void parseBuf(const char* buf, SIZE_ST length)
	{
		if (length > _capacity)
			setCapacity(length);
		memcpy(_buffer, buf, length);
		_wpos = length;
		_rpos = 0;
	}

	template< class T> CReaderStream& operator >> (T& t)
	{
		if (!_buffer)
			return *this;
		SIZE_ST size = (SIZE_ST)sizeof(t);
		if (_wpos - _rpos < size)
			return *this;
		memcpy(&t, _buffer + _rpos, size);
		_rpos += size;
		return *this;
	}

	CReaderStream& operator >> (const char*  &t)
	{
		if (!_buffer)
			return *this;
		SIZE_ST size = *((SIZE_ST*)(_buffer + _rpos));
		if (size > (_wpos - _rpos))
			return *this;
		_rpos += sizeof(SIZE_ST);
		t = _buffer + _rpos;
		_rpos += size + sizeof(char);
		return *this;
	}

	CReaderStream& operator >> ( char*  &t)
	{
		if (!_buffer)
			return *this;
		SIZE_ST size = *((SIZE_ST*)(_buffer + _rpos));
		if (size > (_wpos - _rpos))
			return *this;
		_rpos += sizeof(SIZE_ST);
		t = _buffer + _rpos;
		_rpos += size + sizeof(char);
		return *this;
	}

	//CReaderStream& operator >> (string& t)
	//{
	//	if (!_buffer)
	//		return *this;
	//	SIZE_ST size = *((SIZE_ST*)(_buffer + _rpos));
	//	if (size > (_wpos - _rpos))
	//		return *this;
	//	_rpos += sizeof(SIZE_ST);
	//	t.append(_buffer + _rpos);
	//	_rpos += size + sizeof(char);
	//	return *this;
	//}
public:
	CReaderStream() :_capacity(DEFAULT_DATA_SIZE), _rpos(0), _wpos(0), _buffer(NULL)
	{
		_buffer = (char *)malloc(DEFAULT_DATA_SIZE);
		memset(_buffer, 0, DEFAULT_DATA_SIZE);
	}
	~CReaderStream()
	{
		clear();
	}
};
